import { defineReactive } from './defineReactive.js'
import { Dep } from './dep.js'
import { protoArgument } from './protoArgument.js'
/**
 * 通过Observe类是指响应式
 * @param {*} value 
 */
export function observe(value) {
  // 如果不是对象，就不用设置了
  if (typeof value !== 'object') {
    return
  }
  // 如果已经是响应式的了，就直接返回
  if (value.__ob__) return value.__ob__
  // 返回Observe实例
  return new Observer(value) 
}

/**
 * 为对象设置__ob__属性，标识为响应式对象
 * @param {*} value 
 */
export default function Observer(value) {
  this.dep = new Dep()
  Object.defineProperty(value, '__ob__', {
    value: this,
    enumerable: false, // 禁止枚举（不能使用for in）
    writable: true,
    configurable: true
  })
  // 数组响应式
  if (Array.isArray(value)) {
    // 拦截数组的7个方法达到响应式
    protoArgument(value)
    // 数组响应式的实现
    this.observeArray(value)
  } else {
    // 对象响应式
    this.walk(value)
  }
}
// 定义对象响应式
// 遍历对象的每个属性，对getter,setter进行拦截
Observer.prototype.walk = function(obj) {
  for(let key in obj) {
    defineReactive(obj, key, obj[key])
  } 
}

/**
 * 遍历数组，为每个元素设置响应式，
 * 其实目的是为了arr[index].xx是响应式的
 * @param {*} arr 
 */
Observer.prototype.observeArray = function(arr) {
  for(let item of arr) {
    observe(item)
  }
}